use common::complex::complex::Complex;

const flteps: f64 = 1e-4;
const dbleps: f64 = 1e-6;

#[test]
fn test_cblas_saxpy() {
    let N = 1;
    let alpha = 0.0;
    let X = vec![0.018];
    let incX = 1;
    let mut Y = vec![-0.417];
    let incY = -1;
    let expected = vec![-0.417];
    super::saxpy::cblas_saxpy(N, alpha, &X, incX, &mut Y, incY);
    println!("test_cblas_saxpy::saxpy(case 64): Y: {Y:?}, expected: {expected:?}");
}
#[test]
fn test_cblas_saxpy_1() {
    /*
    https://www.ibm.com/docs/en/essl/6.3?topic=vss-saxpy-daxpy-caxpy-zaxpy-multiply-vector-x-by-scalar-add-vector-y-store-in-vector-y
    Example 1
This example shows vectors x and y with positive strides.
Call Statement and Input:
     */
    // 
    
    let N = 5;
    let alpha = 2.0;
    let X = vec![1.0, 2.0, 3.0, 4.0, 5.0];
    let incX = 1;
    let mut Y = vec![1.0, 9.9, 1.0, 9.9, 1.0, 9.9, 1.0, 9.9, 1.0, 9.9];
    let incY = 2;
    let expected = vec![3.0, 9.9, 5.0, 9.9, 7.0, 9.9, 7.0, 9.9, 11.0, 9.9];
    super::saxpy::cblas_saxpy(N, alpha, &X, incX, &mut Y, incY);
    println!("test_cblas_saxpy::saxpy(Example 1): Y: {Y:?}, expected: {expected:?}");
}

#[test]
fn test_cblas_saxpy_2() {
    /*
    https://www.ibm.com/docs/en/essl/6.3?topic=vss-saxpy-daxpy-caxpy-zaxpy-multiply-vector-x-by-scalar-add-vector-y-store-in-vector-y
    Example 2
This example shows vectors x and y having strides of opposite signs. For y, which has negative stride, processing begins at element Y(5), which is 1.0.
     */
    // 
    
    let N = 5;
    let alpha = 2.0;
    let X = vec![1.0, 2.0, 3.0, 4.0, 5.0];
    let incX = 1;
    let mut Y = X.clone();
    Y.reverse(); // vec![5.0, 4.0, 3.0, 2.0, 1.0];

    let incY = -1;
    let expected = vec![15.0, 12.0, 9.0, 6.0, 3.0];
    super::saxpy::cblas_saxpy(N, alpha, &X, incX, &mut Y, incY);
    println!("test_cblas_saxpy::saxpy(Example 2): Y: {Y:?}, expected: {expected:?}");
}
#[test]
fn test_cblas_saxpy_3() {
    /*
    https://www.ibm.com/docs/en/essl/6.3?topic=vss-saxpy-daxpy-caxpy-zaxpy-multiply-vector-x-by-scalar-add-vector-y-store-in-vector-y
    Example 3
This example shows a vector, x, with 0 stride. Vector x is treated like a vector of length n, all of whose elements are the same as the single element in x.
     */
    // 
    
    let N = 5;
    let alpha = 2.0;
    let X = vec![1.0];
    let incX = 0;
    let mut Y = vec![5.0, 4.0, 3.0, 2.0, 1.0];

    let incY = 1;
    let expected = vec![7.0, 6.0, 5.0, 4.0, 3.0];
    super::saxpy::cblas_saxpy(N, alpha, &X, incX, &mut Y, incY);
    println!("test_cblas_saxpy::saxpy(Example 3): Y: {Y:?}, expected: {expected:?}");
}
#[test]
fn test_cblas_saxpy_4() {
    /*
    https://www.ibm.com/docs/en/essl/6.3?topic=vss-saxpy-daxpy-caxpy-zaxpy-multiply-vector-x-by-scalar-add-vector-y-store-in-vector-y
    Example 4
This example shows how SAXPY can be used to compute a scalar value.
In this case, vectors x and y contain scalar values and the strides for both vectors are 0. The number of elements to be processed, n, is 1.
     */
    // 
    
    let N = 1;
    let alpha = 2.0;
    let X = vec![1.0];
    let incX = 0;
    let mut Y = vec![5.0];

    let incY = 0;
    let expected = vec![7.0];
    super::saxpy::cblas_saxpy(N, alpha, &X, incX, &mut Y, incY);
    println!("test_cblas_saxpy::saxpy(Example 3): Y: {Y:?}, expected: {expected:?}");
}

//   {
//    int N = 1;
//    double alpha = 0;
//    double X[] = { 0.071 };
//    int incX = 1;
//    double Y[] = { -0.888 };
//    int incY = -1;
//    double expected[] = { -0.888 };
//    cblas_daxpy(N, alpha, X, incX, Y, incY);
//    {
//      int i;
//      for (i = 0; i < 1; i++) {
//        gsl_test_rel(Y[i], expected[i], dbleps, "daxpy(case 65)");
//      }
//    };
//   };

//   {
//    int N = 1;
//    double alpha[2] = {-1, 0};
//    double X[] = { 0.003, -0.514 };
//    int incX = 1;
//    double Y[] = { -0.529, 0.743 };
//    int incY = -1;
//    double expected[] = { -0.532, 1.257 };
//    cblas_zaxpy(N, alpha, X, incX, Y, incY);
//    {
//      int i;
//      for (i = 0; i < 1; i++) {
//        gsl_test_rel(Y[2*i], expected[2*i], dbleps, "zaxpy(case 67) real");
//        gsl_test_rel(Y[2*i+1], expected[2*i+1], dbleps, "zaxpy(case 67) imag");
//      };
//    };
//   };

//   {
//    int N = 1;
//    float alpha = 0.1f;
//    float X[] = { 0.771f };
//    int incX = -1;
//    float Y[] = { 0.507f };
//    int incY = 1;
//    float expected[] = { 0.5841f };
//    cblas_saxpy(N, alpha, X, incX, Y, incY);
//    {
//      int i;
//      for (i = 0; i < 1; i++) {
//        gsl_test_rel(Y[i], expected[i], flteps, "saxpy(case 68)");
//      }
//    };
//   };

//   {
//    int N = 1;
//    double alpha = -0.3;
//    double X[] = { 0.029 };
//    int incX = -1;
//    double Y[] = { -0.992 };
//    int incY = 1;
//    double expected[] = { -1.0007 };
//    cblas_daxpy(N, alpha, X, incX, Y, incY);
//    {
//      int i;
//      for (i = 0; i < 1; i++) {
//        gsl_test_rel(Y[i], expected[i], dbleps, "daxpy(case 69)");
//      }
//    };
//   };

#[test]
fn test_cblas_caxpy() {
    let N = 1;
    let alpha = Complex {
        real: -0.3,
        imag: 0.1,
    };
    let X = vec![Complex {
        real: 0.194,
        imag: -0.959,
    }];
    let incX = -1;
    let mut Y = vec![Complex {
        real: 0.096,
        imag: 0.032,
    }];

    let incY = 1;
    let expected = vec![Complex {
        real: 0.1337,
        imag: 0.3391,
    }];
    super::caxpy::cblas_caxpy(N, &alpha, &X, incX, &mut Y, incY);
    println!("\tY: {}\n", Y[0].to_print());
    println!("\texpected: {}\n", expected[0].to_print());
    //    {
    //      int i;
    //      for (i = 0; i < 1; i++) {
    //        gsl_test_rel(Y[2*i], expected[2*i], flteps, "caxpy(case 70) real");
    //        gsl_test_rel(Y[2*i+1], expected[2*i+1], flteps, "caxpy(case 70) imag");
    //      };
    //    };
}


#[test]
fn test_cblas_caxpy_5() {
    /*
    https://www.ibm.com/docs/en/essl/6.3?topic=vss-saxpy-daxpy-caxpy-zaxpy-multiply-vector-x-by-scalar-add-vector-y-store-in-vector-y
    Example 5
This example shows how to use CAXPY, where vectors x and y contain complex numbers. In this case, vectors x and y have positive strides.
     */
    // 
    
    let N = 3;
    let alpha = Complex::new(2.0, 3.0);
    let X = vec![Complex::new(1.0, 2.0), Complex::new(2.0, 0.0), Complex::new(3.0, 5.0)];
    let incX = 1;
    let mut Y = vec![Complex::new(1.0, 1.0), Complex::new(9.9, 9.9), Complex::new(0.0, 2.0), Complex::new(9.9, 9.9), Complex::new(5.0, 4.0)];

    let incY = 2;
    let expected = vec![Complex::new(-3.0, 8.0), Complex::new(9.9, 9.9), Complex::new(4.0, 8.0), Complex::new(9.9, 9.9), Complex::new(-4.0, 23.0)];
    super::caxpy::cblas_caxpy(N, &alpha, &X, incX, &mut Y, incY);
    println!("test_cblas_saxpy::saxpy(Example 5): \n\tY:\t {Y:?},\n\texpected: {expected:?}");
}


//   {
//    int N = 1;
//    double alpha[2] = {0, 1};
//    double X[] = { 0.776, -0.671 };
//    int incX = -1;
//    double Y[] = { 0.39, 0.404 };
//    int incY = 1;
//    double expected[] = { 1.061, 1.18 };
//    cblas_zaxpy(N, alpha, X, incX, Y, incY);
//    {
//      int i;
//      for (i = 0; i < 1; i++) {
//        gsl_test_rel(Y[2*i], expected[2*i], dbleps, "zaxpy(case 71) real");
//        gsl_test_rel(Y[2*i+1], expected[2*i+1], dbleps, "zaxpy(case 71) imag");
//      };
//    };
//   };

//   {
//    int N = 1;
//    float alpha = 1.0f;
//    float X[] = { 0.647f };
//    int incX = -1;
//    float Y[] = { 0.016f };
//    int incY = -1;
//    float expected[] = { 0.663f };
//    cblas_saxpy(N, alpha, X, incX, Y, incY);
//    {
//      int i;
//      for (i = 0; i < 1; i++) {
//        gsl_test_rel(Y[i], expected[i], flteps, "saxpy(case 72)");
//      }
//    };
//   };

//   {
//    int N = 1;
//    double alpha = -1;
//    double X[] = { -0.558 };
//    int incX = -1;
//    double Y[] = { 0.308 };
//    int incY = -1;
//    double expected[] = { 0.866 };
//    cblas_daxpy(N, alpha, X, incX, Y, incY);
//    {
//      int i;
//      for (i = 0; i < 1; i++) {
//        gsl_test_rel(Y[i], expected[i], dbleps, "daxpy(case 73)");
//      }
//    };
//   };

//   {
//    int N = 1;
//    float alpha[2] = {-0.3f, 0.1f};
//    float X[] = { 0.899f, -0.624f };
//    int incX = -1;
//    float Y[] = { 0.155f, -0.33f };
//    int incY = -1;
//    float expected[] = { -0.0523f, -0.0529f };
//    cblas_caxpy(N, alpha, X, incX, Y, incY);
//    {
//      int i;
//      for (i = 0; i < 1; i++) {
//        gsl_test_rel(Y[2*i], expected[2*i], flteps, "caxpy(case 74) real");
//        gsl_test_rel(Y[2*i+1], expected[2*i+1], flteps, "caxpy(case 74) imag");
//      };
//    };
//   };

//   {
//    int N = 1;
//    double alpha[2] = {0, 1};
//    double X[] = { -0.451, 0.768 };
//    int incX = -1;
//    double Y[] = { 0.007, 0.732 };
//    int incY = -1;
//    double expected[] = { -0.761, 0.281 };
//    cblas_zaxpy(N, alpha, X, incX, Y, incY);
//    {
//      int i;
//      for (i = 0; i < 1; i++) {
//        gsl_test_rel(Y[2*i], expected[2*i], dbleps, "zaxpy(case 75) real");
//        gsl_test_rel(Y[2*i+1], expected[2*i+1], dbleps, "zaxpy(case 75) imag");
//      };
//    };
//   };

// }
